home *** CD-ROM | disk | FTP | other *** search
-
- #include <WindowMgr.h>
- #include <ListMgr.h>
- #include <OSUtil.h>
- #include <EventMgr.h>
-
- #include <Strings.h>
- #include <Math.h>
- #include <Ctype.h>
- #include <Stdio.h>
-
- #include "MacCalc.h"
- #include "CalcData.h"
- #include "Parser.h"
-
- unsigned char *curr_pos = NULL ;
- int parse_err = 0 ;
- Str255 buffer ;
-
- /* Simple algabraic expression parser */
-
- double ParseFormula( formula, error )
- unsigned char *formula ;
- int *error ;
- {
- register double value ;
-
- /* convert into c string in buffer */
- BlockMove( &formula[2], buffer, formula[0]-1 ) ;
- buffer[formula[0]-1] = 0 ; /* 0 terminate buffer */
-
- curr_pos = buffer ;
- parse_err = 0 ;
-
- value = ParseExpression( ) ;
-
- *error = parse_err ; /* Set error flag */
-
- return ( value ) ;
- }
- double ParseExpression( )
- {
- register double val ;
-
- val = ParseFactor( ) ;
-
- switch( *curr_pos ) {
- case '+':
- curr_pos++ ;
- val += ParseExpression( ) ;
- break ;
- case '-':
- curr_pos++ ;
- val -= ParseExpression( ) ;
- break ;
- case '*':
- curr_pos++ ;
- val *= ParseExpression( ) ;
- break ;
- case '/':
- curr_pos++ ;
- val /= ParseExpression( ) ;
- break ;
- }
- return val ;
- }
- double ParseFactor( )
- {
- register double val = 0 ;
- register double val2 ;
- register int has_sign = FALSE ;
-
- if( *curr_pos == '-' ) {
- has_sign = TRUE ;
- curr_pos++ ;
- }
-
- if( *curr_pos != '(' ) {
- /* determine whether this is an address or not */
- if( IsDigit( *curr_pos ) || *curr_pos == '.' ) {
- val = ParseValue( ) ;
- }else{
- if( IsFunction( ) ) {
- val = CallFunction( ) ;
- }else{
- val = ParseAddress( ) ;
- }
- }
-
- switch( *curr_pos ) {
- case '^':
- curr_pos++ ;
- val2 = ParseFactor( ) ;
- val = pow( val, val2 ) ;
- break ;
- case '*':
- curr_pos++ ;
- val2 = ParseFactor( ) ;
- val *= val2 ;
- break ;
- case '/':
- curr_pos++ ;
- val2 = ParseFactor( ) ;
- val /= val2 ;
- break ;
- }
- }else{
- curr_pos++ ;
- val = ParseExpression( ) ;
- if( *curr_pos == ')' ) {
- curr_pos++ ;
- }else{
- parse_err = MISMATCHED_PARENTHESIS ;
- }
- }
-
- return ( has_sign ? -( val ):val ) ;
- }
- double ParseValue( )
- {
- register double val = 0 ;
-
- if( IsDigit( *curr_pos ) || ( *curr_pos == '.' ) ) {
- val = atof( ) ;
- }else{
- parse_err = INVALID_NUMBER ;
- }
- return val ;
- }
- double ParseAddress( )
- {
- register int row ;
- register int column ;
- register double val = 0 ;
-
- column = GetColumn( ) ;
- row = GetRow( ) ;
-
- if( ( row > MAX_ROWS ) || ( column > MAX_COLUMNS ) ) {
- parse_err = ADDRESS_TOO_LARGE ;
- }else{
- val = curr_sheet_ptr->sheet_data[row-1][column-1].value ;
- }
- return val ;
- }
- int GetRow( )
- {
- register int row ;
-
- if( IsDigit( *curr_pos ) ) {
- row = *curr_pos - '0' ;
- }else{
- parse_err = INVALID_ADDRESS ;
- }
- curr_pos++ ;
-
- return row ;
- }
- int GetColumn( )
- {
- register int column ;
-
- if( IsAlpha( *curr_pos ) ) {
- if( *curr_pos >= 'a' ) {
- column = ( *curr_pos - 'a' ) + 1 ;
- }else{
- column = ( *curr_pos - 'A' ) + 1 ;
- }
- }else{
- parse_err = INVALID_ADDRESS ;
- }
- curr_pos++ ;
-
- return column ;
- }
- int IsFunction( )
- {
- register unsigned char *p ;
-
- p = curr_pos ;
- while( IsAlpha( *p ) || IsDigit( *p ) ) {
- p++ ;
- }
- return ( *p == '(' ) ? TRUE:FALSE ;
- }
- double CallFunction( )
- {
- unsigned char fun_name[32] ;
- register unsigned char *p ;
- register int fun_number ;
- register double value ;
- register ARG_PTR args ;
-
- p = fun_name ;
-
- while( IsAlpha( *curr_pos ) || IsDigit( *curr_pos ) ) {
- *p = toupper( *curr_pos ) ;
- p++; curr_pos++;
- }
- *p = '\0' ;
- curr_pos++ ;
-
- args = BuildArg( ) ;
-
- if( ( fun_number = Lookup( fun_name ) ) > -1 ) {
- value = (*fun_table[fun_number].fun_ptr)( args ) ;
- }else{
- parse_err = INVALID_FUNCTION ;
- }
- DestroyArgs( args ) ;
- return value ;
- }
- int Lookup( fun_name )
- unsigned char *fun_name ;
- {
- register int i = 0 ;
-
- while( fun_table[i].fun_name[0] != 0 ) {
- if( !strcmp( fun_name, fun_table[i].fun_name ) ) {
- return i ;
- }
- i++ ;
- }
- return -1 ;
- }
- ARG_PTR BuildArg( )
- {
- int error ;
- ARG_PTR first_arg_ptr = NULL, last_arg_ptr = NULL, next_arg_ptr = NULL ;
-
- /* This needs to be changed so that recursive functions calls can be
- made */
- while( *curr_pos != ')' ) {
- next_arg_ptr = GetArg( ) ;
- next_arg_ptr->value = ParseExpression( ) ;
- next_arg_ptr->type = VALUE_ARG ;
- if( *curr_pos == ',' ) {
- curr_pos++ ;
- }
- if( last_arg_ptr != NULL ) {
- last_arg_ptr->next_arg = next_arg_ptr ;
- }
- if( first_arg_ptr == NULL ) {
- first_arg_ptr = next_arg_ptr ;
- }
- last_arg_ptr = next_arg_ptr ;
- }
- next_arg_ptr->next_arg = NULL ;
-
- /* Now pass the last parenthesis by */
- if( *curr_pos == ')' ) {
- curr_pos++ ;
- return first_arg_ptr ;
- }else{
- parse_err = MISMATCHED_PARENTHESIS ;
- return NULL ;
- }
- }
- double atof( )
- {
- register double val = 0.0 ;
- register double val2 = 0.0 ;
-
- if( IsDigit( *curr_pos ) || ( *curr_pos == '.' ) ) {
- while( *curr_pos && IsDigit( *curr_pos ) ) {
- val = ( val * 10 ) + ( *curr_pos - '0' ) ;
- curr_pos++ ;
- }
- if( *curr_pos == '.' ) {
- curr_pos++ ;
- }
- while( *curr_pos && IsDigit( *curr_pos ) ) {
- val2 = ( val2 * 10 ) + ( *curr_pos - '0' ) ;
- curr_pos++ ;
- }
- if( val2 != 0.0 ) {
- while( val2 > 1 ) {
- val2 /= 10 ;
- }
- }
- val += val2 ;
- }else{
- parse_err = INVALID_NUMBER ;
- }
- return val ;
-
- }
- void ftoa( val, buffer )
- double val ;
- unsigned char *buffer ;
- {
- long whole ;
- Str255 buff ;
- Str255 tmp ;
- int has_sign ;
- int prec = /*curr_precision*/5 ;
-
- has_sign = ( val < 0 ) ? TRUE:FALSE ;
- val = ( val<0 ) ? -val:val ; /* <- */
- whole = val/1 ;
- NumToString( whole, buffer ) ;
- /* convert into c string in buffer */
- BlockMove( &buffer[1], buff, buffer[0] ) ;
- buff[buffer[0]] = 0 ; /* 0 terminate buffer */
- val -= whole ;
- if( prec ) {
- do{
- val *= 10.0 ;
- }while( --prec ) ;
- whole = val ;
- NumToString( whole, buffer ) ;
- /* convert into c string in buffer */
- BlockMove( &buffer[1], tmp, buffer[0] ) ;
- tmp[buffer[0]] = 0 ; /* 0 terminate buffer */
- strcat( buff, "." ) ;
- strcat( buff, tmp ) ;
- }
- if( has_sign ) {
- tmp[0] = '-' ;
- tmp[1] = '\0' ;
- strcat( tmp, buff ) ;
- strcpy( &buffer[1], tmp ) ;
- buffer[0] = strlen( tmp ) ;
- }else{
- strcpy( &buffer[1], buff ) ;
- buffer[0] = strlen( buff ) ;
- }
-
- return ;
- }
- double GetFloat( formula, error )
- unsigned char *formula ;
- int *error ;
- {
- register double value ;
-
- /* convert into c string in buffer */
- BlockMove( &formula[1], buffer, formula[0] ) ;
- buffer[formula[0]] = 0 ; /* 0 terminate buffer */
-
- curr_pos = buffer ;
- parse_err = 0 ;
-
- value = atof( ) ;
-
- *error = parse_err ; /* Set error flag */
-
- return ( value ) ;
- }
- ARG_PTR GetArg( )
- {
- register int i ;
-
- for( i=0;i<30;i++){
- if( arg_free_pool[i].in_use == FREE_ARG ) {
- arg_free_pool[i].in_use = IN_USE ;
- return &arg_free_pool[i] ;
- }
- }
- return NULL ;
- }
- void DestroyArgs( arg_ptr )
- ARG_PTR arg_ptr ;
- {
- if( arg_ptr != NULL ) {
- PutArg( arg_ptr ) ;
- while( arg_ptr->next_arg != NULL ) {
- arg_ptr = arg_ptr->next_arg ;
- PutArg( arg_ptr ) ;
- }
- }
- return ;
- }
- void PutArg( arg_ptr )
- ARG_PTR arg_ptr ;
- {
- arg_ptr->in_use = FREE_ARG ;
- return ;
- }
-